package com.haixiaoke.saas.org.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.haixiaoke.saas.common.constant.UserConstants;
import com.haixiaoke.saas.common.core.domain.AjaxResult;
import com.haixiaoke.saas.common.exception.ServiceException;
import com.haixiaoke.saas.common.utils.DateUtils;
import com.haixiaoke.saas.common.utils.tree.TreeUtil;
import com.haixiaoke.saas.org.domain.Dept;
import com.haixiaoke.saas.org.domain.DeptTree;
import com.haixiaoke.saas.org.mapper.DeptMapper;
import com.haixiaoke.saas.org.service.IDeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 部门Service业务层处理
 * 
 * @author panda
 * @date 2025-06-03
 */
@Service
public class DeptServiceImpl implements IDeptService {
    @Autowired
    private DeptMapper deptMapper;

    /**
     * 查询部门
     * 
     * @param deptId 部门主键
     * @return 部门
     */
    @Override
    public Dept selectDeptByDeptId(Long deptId) {
        return deptMapper.selectDeptByDeptId(deptId);
    }

    @Override
    public List<DeptTree> buildTreeList(Dept bizDept) {
        List<DeptTree> deptLists = deptMapper.selectDeptTreeList(bizDept);
        return TreeUtil.generateTree(deptLists);
    }

    /**
     * 查询部门列表
     * 
     * @param dept 部门
     * @return 部门
     */
    @Override
    public List<Dept> selectDeptList(Dept dept) {
        return deptMapper.selectDeptList(dept);
    }

    /**
     * 新增部门
     * 
     * @param dept 部门
     * @return 结果
     */
    @Override
    public AjaxResult insertDept(Dept dept) {
        List<Map<String, Object>> maps = deptMapper.checkParams(dept);
        if (CollectionUtil.isNotEmpty(maps)) {
            for (Map<String, Object> map : maps) {
                if (Integer.parseInt(map.get("num").toString()) > 0) {
                    String type = map.get("type").toString();
                    switch (type) {
                        case "1":
                            return AjaxResult.error("权限字符已存在，请重新输入");
                        case "2":
                            return AjaxResult.error("部门名称已存在，请重新输入");
                    }
                }
            }
        }
        dept.setCreateTime(DateUtils.getNowDate());
        Dept deptByPartId = deptMapper.selectDeptByDeptId(dept.getParentId());
        if (ObjectUtil.isNotEmpty(deptByPartId)) {
            if (!UserConstants.DEPT_NORMAL.equals(deptByPartId.getStatus())) {
                return AjaxResult.error("部门停用，不允许新增");
            }
            if (!dept.getParentId().equals(deptByPartId.getParentId())) {
                dept.setAncestors(deptByPartId.getAncestors() + "," + dept.getParentId());
            }
        } else {
            dept.setAncestors(String.valueOf(dept.getParentId()));
        }
        deptMapper.insertDept(dept);
        return AjaxResult.success();
    }

    /**
     * 修改部门
     * 
     * @param dept 部门
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult updateDept(Dept dept) {
        List<Map<String, Object>> maps = deptMapper.checkParams(dept);
        if (CollectionUtil.isNotEmpty(maps)) {
            for (Map<String, Object> map : maps) {
                if (Integer.parseInt(map.get("num").toString()) > 0) {
                    String type = map.get("type").toString();
                    switch (type) {
                        case "1":
                            return AjaxResult.error("权限字符已存在，请重新输入");
                        case "2":
                            return AjaxResult.error("部门名称已存在，请重新输入");
                    }
                }
            }
        }
        if (dept.getDeptId().equals(dept.getParentId())) {
            return AjaxResult.error("数据异常，不能设置自己为父级结构");
        }
        dept.setUpdateTime(DateUtils.getNowDate());
        Dept parentDept = deptMapper.selectDeptByDeptId(dept.getParentId());
        Dept deptByDeptId = deptMapper.selectDeptByDeptId(dept.getDeptId());
        if (ObjectUtil.isNotEmpty(parentDept) && ObjectUtil.isNotEmpty(deptByDeptId)) {
            String newAncestors = parentDept.getAncestors() + "," + parentDept.getDeptId();
            String oldAncestors = deptByDeptId.getAncestors();
            dept.setAncestors(newAncestors);
            updateDeptChildren(dept, newAncestors, oldAncestors);
        } else if (ObjectUtil.isEmpty(parentDept) && ObjectUtil.isNotEmpty(deptByDeptId)) {
            String newAncestors = "0";
            String oldAncestors = deptByDeptId.getAncestors();
            dept.setAncestors(newAncestors);
            updateDeptChildren(dept, newAncestors, oldAncestors);
        }
        deptMapper.updateDept(dept);
        return AjaxResult.success();
    }

    /**
     * 批量删除部门
     * 
     * @param deptIds 需要删除的部门主键
     * @return 结果
     */
    @Override
    public int deleteDeptByDeptIds(Long[] deptIds) {
        return deptMapper.deleteDeptByDeptIds(deptIds);
    }

    /**
     * 删除部门信息
     * 
     * @param deptId 部门主键
     * @return 结果
     */
    @Override
    public int deleteDeptByDeptId(Long deptId) {
        return deptMapper.deleteDeptByDeptId(deptId);
    }

    @Override
    public int softDeleteDeptByDeptId(Long deptId) {
        return deptMapper.softDeleteDeptByDeptId(deptId);
    }

    /**
     * 查询是否有下级部门
     *
     * @param deptId
     * @return
     */
    @Override
    public boolean hasChildByDeptId(Long deptId) {
        int result = deptMapper.hasChildByDeptId(deptId);
        return result > 0;
    }

    /**
     * 查询部门是否有用户
     *
     * @param deptId
     * @return
     */
    @Override
    public boolean checkDeptExistUser(Long deptId) {
        int result = deptMapper.checkDeptExistUser(deptId);
        return result > 0;
    }

    @Override
    public Dept selectDeptByPermissionChar(String permissionChar) {
        return deptMapper.selectDeptByPermissionChar(permissionChar);
    }

    private void updateDeptChildren(Dept dept, String newAncestors, String oldAncestors) {
        Date nowDate = DateUtils.getNowDate();
        List<Dept> deptList = deptMapper.selectDeptChildrenByDeptId(dept.getDeptId());
        for (Dept deptById : deptList) {
            deptById.setAncestors(dept.getAncestors().replaceFirst(oldAncestors, newAncestors));
            deptById.setUpdateTime(nowDate);
            deptById.setUpdateBy(dept.getUpdateBy());
        }
        if (!deptList.isEmpty()) {
            deptMapper.updateBatchDept(deptList);
        }
    }
}
